Implement support for throw expressions in expression trees#19
Implement support for throw expressions in expression trees#19
Conversation
tests/ExpressiveSharp.IntegrationTests.ExpressionCompile/Tests/Common/ThrowExpressionTests.cs
Dismissed
Show dismissed
Hide dismissed
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Pull request overview
This PR adds end-to-end support for C# throw expressions in ExpressiveSharp-generated expression trees, including emission, EF Core compatibility behavior, and test/docs updates.
Changes:
- Added generator emission for
IThrowOperation(including typedExpression.Throw(exception, typeof(T))) and updated block-body handling to allow throws. - Added an EF Core-facing transformer (
ReplaceThrowWithDefault) and an EF configuration switch to preserve throws instead of replacing them. - Added/updated unit, generator snapshot, and integration tests plus documentation to cover throw-expression scenarios.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/ExpressiveSharp.Tests/Transformers/ReplaceThrowWithDefaultTests.cs | Adds unit tests validating throw→default rewriting behavior. |
| tests/ExpressiveSharp.IntegrationTests/Scenarios/Store/Models/Order.cs | Adds [Expressive] property using ?? throw as a real scenario. |
| tests/ExpressiveSharp.IntegrationTests/Scenarios/Common/Tests/ThrowExpressionTests.cs | Adds scenario tests for SafeTag expansion behavior. |
| tests/ExpressiveSharp.IntegrationTests.ExpressionCompile/Tests/Common/ThrowExpressionTests.cs | Wires the scenario tests into the ExpressionCompile runner. |
| tests/ExpressiveSharp.Generator.Tests/ExpressiveGenerator/ThrowExpressionTests.cs | Adds generator tests for throw in coalesce/conditional/switch arm. |
| tests/ExpressiveSharp.Generator.Tests/ExpressiveGenerator/*.verified.txt | Snapshot outputs for new throw-expression generator cases. |
| tests/ExpressiveSharp.Generator.Tests/ExpressiveGenerator/DiagnosticTests.cs | Removes prior “throw is unsupported” diagnostic test. |
| tests/ExpressiveSharp.Generator.Tests/ExpressiveGenerator/BlockBodyTests.cs + verified | Updates expectations: throw in block bodies is now emitted, not warned. |
| src/ExpressiveSharp/Transformers/ReplaceThrowWithDefault.cs | Introduces the transformer used to remove throw nodes for provider compatibility. |
| src/ExpressiveSharp.Generator/Interpretation/ExpressiveInterpreter.BodyProcessors.cs | Stops flagging IThrowOperation as unsupported in block bodies. |
| src/ExpressiveSharp.Generator/Emitter/ExpressionTreeEmitter.cs | Implements throw emission and conversion special-casing for throw operands. |
| src/ExpressiveSharp.EntityFrameworkCore/.../ExpressiveOptionsExtension.cs | Adds default throw-stripping behavior for EF Core, plus opt-out. |
| src/ExpressiveSharp.EntityFrameworkCore/Extensions/DbContextOptionsExtensions.cs | Passes the new preserve-throws option into the EF extension. |
| src/ExpressiveSharp.EntityFrameworkCore/ExpressiveOptionsBuilder.cs | Adds PreserveThrowExpressions() option for EF integration configuration. |
| docs/advanced/ioperation-mapping.md | Documents IThrowOperation mapping and EF compatibility behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
tests/ExpressiveSharp.IntegrationTests/Scenarios/Common/Tests/ThrowExpressionTests.cs
Show resolved
Hide resolved
| Expression<Func<Order, string>> expr = o => o.SafeTag; | ||
| var expanded = (Expression<Func<Order, string>>)expr.ExpandExpressives(); | ||
|
|
||
| // Compile and invoke directly — non-null Tag should return the value | ||
| var compiled = expanded.Compile(); | ||
| var order = new Order { Tag = "RUSH" }; | ||
| Assert.AreEqual("RUSH", compiled(order)); | ||
| } |
There was a problem hiding this comment.
These integration tests compile/invoke the expanded expression directly instead of executing it via Runner (like other scenario tests do). As a result, they don’t actually validate behavior across integration runners / LINQ providers and won’t catch translation-time issues.
tests/ExpressiveSharp.Generator.Tests/ExpressiveGenerator/ThrowExpressionTests.cs
Outdated
Show resolved
Hide resolved
...Sharp.Generator.Tests/ExpressiveGenerator/ThrowExpressionTests.ThrowInSwitchArm.verified.txt
Outdated
Show resolved
Hide resolved
src/ExpressiveSharp.EntityFrameworkCore/ExpressiveOptionsBuilder.cs
Outdated
Show resolved
Hide resolved
| [TestClass] | ||
| public class ThrowExpressionTests : Scenarios.Common.Tests.ThrowExpressionTests | ||
| { | ||
| protected override IIntegrationTestRunner CreateRunner() => new ExpressionCompileTestRunner(); |
There was a problem hiding this comment.
This adds the scenario test to the ExpressionCompile runner, but there’s no corresponding derived test in ExpressiveSharp.IntegrationTests.EntityFrameworkCore (search shows no ThrowExpressionTests there). To validate provider compatibility as described in the PR, add the EF Core runner variant as well.
Add support for throw expressions in expression trees, enabling their use in null-coalescing and other scenarios. Include tests to verify correct behavior and ensure compatibility with LINQ providers. Update related components to handle throw expressions appropriately.